package cn.lili.modules.promotion.serviceimpl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.lili.cache.Cache;
import cn.lili.common.enums.PromotionTypeEnum;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.security.enums.SceneEnums;
import cn.lili.common.utils.SnowFlake;
import cn.lili.common.utils.StringUtils;
import cn.lili.common.vo.PageVO;
import cn.lili.modules.goods.client.GoodsClient;
import cn.lili.modules.goods.entity.dos.Goods;
import cn.lili.modules.goods.entity.dos.GoodsSku;
import cn.lili.modules.goods.entity.dto.GoodsSearchParams;
import cn.lili.modules.promotion.entity.dos.BaseStandardPromotions;
import cn.lili.modules.promotion.entity.dos.PromotionGoods;
import cn.lili.modules.promotion.entity.dos.Seckill;
import cn.lili.modules.promotion.entity.dos.SeckillApply;
import cn.lili.modules.promotion.entity.dto.SeckillAutidDTO;
import cn.lili.modules.promotion.entity.dto.search.PromotionGoodsSearchParams;
import cn.lili.modules.promotion.entity.dto.search.SeckillSearchParams;
import cn.lili.modules.promotion.entity.enums.PromotionsApplyStatusEnum;
import cn.lili.modules.promotion.entity.vos.SeckillApplyVO;
import cn.lili.modules.promotion.entity.vos.SeckillGoodsVO;
import cn.lili.modules.promotion.entity.vos.SeckillTimelineVO;
import cn.lili.modules.promotion.mapper.SeckillApplyMapper;
import cn.lili.modules.promotion.service.PromotionGoodsService;
import cn.lili.modules.promotion.service.SeckillApplyService;
import cn.lili.modules.promotion.service.SeckillService;
import cn.lili.modules.promotion.tools.PromotionTools;
import cn.lili.modules.system.client.SettingClient;
import cn.lili.modules.system.entity.dos.Setting;
import cn.lili.modules.system.entity.dto.SeckillSetting;
import cn.lili.modules.system.entity.enums.SettingEnum;
import cn.lili.mybatis.util.PageUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.gson.Gson;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.apache.shardingsphere.transaction.annotation.ShardingTransactionType;
import org.apache.shardingsphere.transaction.core.TransactionType;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 秒杀申请业务层实现
 *
 * @author Chopper
 * @since 2020/8/21
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class SeckillApplyServiceImpl extends ServiceImpl<SeckillApplyMapper, SeckillApply> implements SeckillApplyService {

    /**
     * 缓存
     */
    private final Cache<Object> cache;
    /**
     * 规格商品
     */
    private final GoodsClient goodsClient;
    /**
     * 促销商品
     */
    private final PromotionGoodsService promotionGoodsService;
    /**
     * 秒杀
     */
    private final SeckillService seckillService;
    /**
     * 秒杀
     */
    private final SettingClient settingClient;

    @Override
    public List<SeckillTimelineVO> getSeckillTimeline() {
        //秒杀活动缓存key
        return getSeckillTimelineInfo();
    }

    @Override
    public List<SeckillGoodsVO> getSeckillGoods(Integer timeline) {
        List<SeckillGoodsVO> seckillGoodsVoS = new ArrayList<>();
        //获取
        List<SeckillTimelineVO> seckillTimelineToCache = getSeckillTimelineInfo();
        Optional<SeckillTimelineVO> first = seckillTimelineToCache.stream().filter(i -> i.getTimeLine().equals(timeline)).findFirst();
        if (first.isPresent()) {
            seckillGoodsVoS = first.get().getSeckillGoodsList();
        } else if (!seckillTimelineToCache.isEmpty()) {
            seckillGoodsVoS = seckillTimelineToCache.get(getSeckillTimeline().size() - 1).getSeckillGoodsList();
        }
        return seckillGoodsVoS;
    }

    @Override
    public Page<SeckillApply> getSeckillApplyPage(SeckillSearchParams queryParam, PageVO pageVo) {
        QueryWrapper<SeckillApply> queryWrapper = queryParam.queryWrapper();
        // 根据goods_id去重
        queryWrapper.groupBy("goods_id");
        Page<SeckillApply> seckillApplyPage = this.page(PageUtil.initPage(pageVo), queryWrapper);
        if (seckillApplyPage != null && !seckillApplyPage.getRecords().isEmpty()) {

            //获取skuId
            List<String> skuIds = seckillApplyPage.getRecords().stream().map(SeckillApply::getSkuId).collect(Collectors.toList());

            //循环获取 店铺/全平台 参与的促销商品库存进行填充
            if (!skuIds.isEmpty()) {
                List<Integer> skuStock = promotionGoodsService.getPromotionGoodsStock(PromotionTypeEnum.SECKILL, queryParam.getSeckillId(), skuIds);
                for (int i = 0; i < skuIds.size(); i++) {
                    seckillApplyPage.getRecords().get(i).setQuantity(skuStock.get(i));
                }
            }

            seckillApplyPage.getRecords().forEach(seckillApply -> {
                if (StringUtils.isNotEmpty(seckillApply.getGoodsId())) {
                    Goods goods = goodsClient.getById(seckillApply.getGoodsId());
                    seckillApply.setGoodsName(goods.getGoodsName());
                }
            });

            //Iterator<SeckillApply> iterator = seckillApplyPage.getRecords().iterator();
        }
        return seckillApplyPage;
    }

    /**
     * 分页查询限时请购申请列表
     *
     * @param queryParam 秒杀活动申请查询参数
     * @return 限时请购申请列表
     */
    @Override
    public List<SeckillApply> getSeckillApplyList(SeckillSearchParams queryParam) {
        return this.list(queryParam.queryWrapper());
    }

    /**
     * 查询限时请购申请列表总数
     *
     * @param seckillId 秒杀活动
     * @return 限时请购申请列表总数
     */
    @Override
    public long getSeckillApplyCount(String seckillId) {
        SeckillSearchParams queryParam = new SeckillSearchParams();
        queryParam.setSeckillId(seckillId);
        queryParam.setPromotionApplyStatus(PromotionsApplyStatusEnum.PASS.name());
        return this.count(queryParam.queryWrapper());
    }

    /**
     * 查询限时请购申请
     *
     * @param queryParam 秒杀活动申请查询参数
     * @return 限时请购申请
     */
    @Override
    public SeckillApply getSeckillApply(SeckillSearchParams queryParam) {
        return this.getOne(queryParam.queryWrapper(), false);
    }

    @Override
    @Transactional
    public void addSeckillApply(String seckillId, String storeId, List<SeckillApplyVO> seckillApplyList) {


        //获取秒杀活动设置
        Setting setting = settingClient.get(SettingEnum.SECKILL_SETTING.name());
        SeckillSetting seckillSetting = new Gson().fromJson(setting.getSettingValue(), SeckillSetting.class);

        //获取秒杀活动信息
        Seckill seckill = this.seckillService.getById(seckillId);
        if (seckill == null) {
            throw new ServiceException(ResultCode.SECKILL_NOT_EXIST_ERROR);
        }
        if (seckillApplyList == null || seckillApplyList.isEmpty()) {
            return;
        }
        //检查秒杀活动申请是否合法
        checkSeckillApplyList(seckill.getHours(), seckillApplyList);
        //获取已参与活动的秒杀活动活动申请列表
        List<String> skuIds = seckillApplyList.stream().map(SeckillApply::getSkuId).collect(Collectors.toList());
        //数据库持久化对象集合
        List<SeckillApply> seckillApplies = new ArrayList<>();
        List<PromotionGoods> promotionGoodsList = new ArrayList<>();
        System.out.println("秒杀活动老的商品数量");
        for (SeckillApplyVO seckillApply : seckillApplyList) {
            //获取参与活动的商品信息
            GoodsSku goodsSku = goodsClient.getCanPromotionGoodsSkuByIdFromCache(seckillApply.getSkuId());
            /*if(goodsSku.getGreenScore() != 0) {
                throw new ServiceException("商品绿色积分设置不为0，无法设置秒杀");
            }*/
//            if (!goodsSku.getStoreId().equals(storeId)) {
//                continue;
//            }
            //获取秒杀活动时间段
            DateTime startTime = DateUtil.offsetHour(seckill.getStartTime(), seckillApply.getTimeLine());
            //检测是否可以发布促销商品
            checkSeckillGoodsSku(seckill, seckillApply, goodsSku, startTime);
            //设置秒杀申请默认内容
            //seckillApply.setOriginalPrice(goodsSku.getPrice());

            if (Boolean.TRUE.equals(seckillSetting.getNeedCheck())) {
                seckillApply.setPromotionApplyStatus(PromotionsApplyStatusEnum.APPLY.name());
            } else {
                seckillApply.setPromotionApplyStatus(PromotionsApplyStatusEnum.PASS.name());
            }
            if (null != seckillApply.getVirtualSalesNum()) {
                seckillApply.setSalesNum(seckillApply.getVirtualSalesNum());
            }else {
                seckillApply.setSalesNum(0);
            }

            seckillApply.setOriginalQuantity(seckillApply.getQuantity());

            seckillApplies.add(seckillApply);
            //获取促销商品
            PromotionGoods promotionGoods = this.setSeckillGoods(goodsSku, seckillApply, seckill);
            if (null != seckillApply.getVirtualSalesNum()) {
                promotionGoods.setNum(seckillApply.getVirtualSalesNum());
            }
            //审核通过的秒杀活动，才进行添加
            if (seckillApply.getPromotionApplyStatus().equals(PromotionsApplyStatusEnum.PASS.name())) {
                promotionGoodsList.add(promotionGoods);
            }
        }

        //删除之前存储的秒杀活动商品，否则重复添加这里数据会重复
        this.remove(new LambdaQueryWrapper<SeckillApply>().eq(SeckillApply::getSeckillId, seckillId).in(SeckillApply::getSkuId, skuIds));
        //保存新的数据，重新计算id
        for (SeckillApply seckillApply:seckillApplies) {
            seckillApply.setId(SnowFlake.getIdStr());
        }

        //重新赋值id
        List<SeckillApply> updatedSeckillApplies = seckillApplies.stream()
                .peek(seckillApply -> seckillApply.setId(SnowFlake.getIdStr())).toList();

        this.saveBatch(updatedSeckillApplies);

        //保存促销活动商品信息
        if (!promotionGoodsList.isEmpty()) {
            PromotionGoodsSearchParams searchParams = new PromotionGoodsSearchParams();
            searchParams.setPromotionId(seckillId);
            searchParams.setStoreId(storeId);
            searchParams.setPromotionType(PromotionTypeEnum.SECKILL.name());
            searchParams.setSkuIds(promotionGoodsList.stream().map(PromotionGoods::getSkuId).collect(Collectors.toList()));
            promotionGoodsService.deletePromotionGoods(searchParams);
            //初始化促销商品
            PromotionTools.promotionGoodsInit(promotionGoodsList, seckill, PromotionTypeEnum.SECKILL);
            promotionGoodsService.saveBatch(promotionGoodsList);


            //设置秒杀活动的商品数量
            seckillService.updateSeckillGoodsNum(seckillId, getSeckillApplyCount(seckillId));
            this.seckillService.updateEsGoodsSeckill(seckill, seckillApplies);
        }
    }


    /**
     * 批量删除秒杀活动申请
     *
     * @param seckillId 秒杀活动活动id
     * @param id        id
     */
    @Override
    @Transactional
    public void removeSeckillApply(String seckillId, String storeId, String id) {
        Seckill seckill = this.seckillService.getById(seckillId);
        if (seckill == null) {
            throw new ServiceException(ResultCode.SECKILL_NOT_EXIST_ERROR);
        }
        SeckillApply seckillApply = this.getById(id);
        if (seckillApply == null) {
            throw new ServiceException(ResultCode.SECKILL_APPLY_NOT_EXIST_ERROR);
        }

        GoodsSku goodsSku = goodsClient.getCanPromotionGoodsSkuByIdFromCache(seckillApply.getSkuId());

        if(goodsSku != null && !"-1".equals(storeId) && !storeId.equals(goodsSku.getStoreId())) {
            throw new ServiceException("您不能删除其他店铺的商品");
        }

        List<SeckillApply> seckillApplyList = this.list(new LambdaQueryWrapper<SeckillApply>().eq(SeckillApply::getGoodsId, seckillApply.getGoodsId()));

        //清除秒杀活动中的商品
        this.remove(new LambdaQueryWrapper<SeckillApply>().eq(SeckillApply::getSeckillId, seckillId).in(SeckillApply::getGoodsId, seckillApply.getGoodsId()));

        this.seckillService.deleteEsGoodsSeckill(seckill, seckillApplyList.stream().map(SeckillApply::getSkuId).toList());
        //删除促销商品
        this.promotionGoodsService.deletePromotionGoods(seckillId, seckillApplyList.stream().map(SeckillApply::getSkuId).toList());
    }

    /**
     * 更新秒杀商品出售数量
     *
     * @param seckillId 秒杀活动id
     * @param skuId     商品skuId
     * @param saleNum   库存
     */
    @Override
    public void updateSeckillApplySaleNum(String seckillId, String skuId, Integer saleNum) {
        LambdaUpdateWrapper<SeckillApply> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(SeckillApply::getSeckillId, seckillId).eq(SeckillApply::getSkuId, skuId);
        updateWrapper.set(SeckillApply::getSalesNum, saleNum);
        this.update(updateWrapper);
    }

    /**
     * 更新秒杀活动时间
     *
     * @param seckill 秒杀活动
     * @return 是否更新成功
     */
    @Override
    @Transactional
    @ShardingTransactionType(TransactionType.BASE)
    public boolean updateSeckillApplyTime(Seckill seckill) {
        boolean result = false;
        List<PromotionGoods> promotionGoodsList = new ArrayList<>();
        LambdaQueryWrapper<SeckillApply> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SeckillApply::getSeckillId, seckill.getId());
        List<SeckillApply> list =
                this.list(queryWrapper).stream().filter(i -> i.getTimeLine() != null && seckill.getHours().contains(i.getTimeLine().toString())).collect(Collectors.toList());
        for (SeckillApply seckillApply : list) {
            //获取参与活动的商品信息
            GoodsSku goodsSku = goodsClient.getCanPromotionGoodsSkuByIdFromCache(seckillApply.getSkuId());
            //获取促销商品
            PromotionGoods promotionGoods = this.setSeckillGoods(goodsSku, seckillApply, seckill);
            promotionGoodsList.add(promotionGoods);
        }
        //保存促销活动商品信息
        if (!promotionGoodsList.isEmpty()) {
            PromotionGoodsSearchParams searchParams = new PromotionGoodsSearchParams();
            searchParams.setPromotionType(PromotionTypeEnum.SECKILL.name());
            searchParams.setPromotionId(seckill.getId());
            promotionGoodsService.deletePromotionGoods(searchParams);
            //初始化促销商品
            List<PromotionGoods> promotionGoods = PromotionTools.promotionGoodsInit(promotionGoodsList, seckill, PromotionTypeEnum.SECKILL);
            result = promotionGoodsService.saveBatch(promotionGoods);
            this.seckillService.updateEsGoodsSeckill(seckill, list);

            LambdaQueryWrapper<SeckillApply> deleteWrapper = new LambdaQueryWrapper<>();
            deleteWrapper.eq(SeckillApply::getSeckillId, seckill.getId());
            deleteWrapper.notIn(SeckillApply::getSkuId, promotionGoodsList.stream().map(PromotionGoods::getSkuId).collect(Collectors.toList()));
            this.remove(deleteWrapper);
        }
        return result;
    }

    @Override
    public void auditSeckillApply(SeckillAutidDTO seckillAutidDTO) {
        if (!UserContext.getCurrentUser().getScene().equals(SceneEnums.MANAGER)) {
            throw new ServiceException(ResultCode.USER_AUTHORITY_ERROR);
        }
        Seckill seckill = seckillService.getById(seckillAutidDTO.getSeckillId());
        if (seckill == null) {
            return;
        }

        UpdateWrapper<SeckillApply> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set("promotion_apply_status", seckillAutidDTO.getPromotionApplyStatus());
        updateWrapper.set("fail_reason", seckillAutidDTO.getFailReason());
        updateWrapper.in("id", seckillAutidDTO.getIds());
        updateWrapper.eq("seckill_id", seckillAutidDTO.getSeckillId());
        updateWrapper.eq("promotion_apply_status", PromotionsApplyStatusEnum.APPLY.name());
        this.update(updateWrapper);


        //审核通过则生成相关数据
        if (seckillAutidDTO.getPromotionApplyStatus().equals(PromotionsApplyStatusEnum.PASS)) {

            List<PromotionGoods> promotionGoodsList = new ArrayList<>();
            for (String id : seckillAutidDTO.getIds()) {

                SeckillApply seckillApply = this.getById(id);
                if (seckillApply == null) {
                    continue;
                }

                //获取参与活动的商品信息
                GoodsSku goodsSku = goodsClient.getCanPromotionGoodsSkuByIdFromCache(seckillApply.getSkuId());
                if (goodsSku == null) {
                    continue;
                }

                //获取促销商品
                PromotionGoods promotionGoods = this.setSeckillGoods(goodsSku, seckillApply, seckill);
                promotionGoodsList.add(promotionGoods);

                PromotionTools.promotionGoodsInit(promotionGoodsList, seckill, PromotionTypeEnum.SECKILL);

            }

            promotionGoodsService.saveBatch(promotionGoodsList);
            reGenerateEs(seckillAutidDTO.getSeckillId());
        }
    }

    /**
     * 重新生成
     *
     * @param seckillId 秒杀活动id
     */
    private void reGenerateEs(String seckillId) {

        //获取秒杀活动信息
        Seckill seckill = seckillService.getById(seckillId);

        SeckillSearchParams searchParams = new SeckillSearchParams();
        searchParams.setSeckillId(seckillId);
        searchParams.setPromotionApplyStatus(PromotionsApplyStatusEnum.PASS.name());

        this.seckillService.updateEsGoodsSeckill(seckill, this.getSeckillApplyList(searchParams));

    }

    /**
     * 检查秒杀活动申请列表参数信息
     *
     * @param hours            秒杀活动时间段
     * @param seckillApplyList 秒杀活动申请列表
     */
    private void checkSeckillApplyList(String hours, List<SeckillApplyVO> seckillApplyList) {
        List<String> existSku = new ArrayList<>();
        for (SeckillApplyVO seckillApply : seckillApplyList) {
            if (seckillApply.getPrice() > seckillApply.getOriginalPrice()) {
                throw new ServiceException(ResultCode.SECKILL_PRICE_ERROR);
            }
            //检查秒杀活动申请的时刻，是否存在在秒杀活动的时间段内
            String[] rangeHours = hours.split(",");
            boolean containsSame = Arrays.stream(rangeHours).anyMatch(i -> i.equals(seckillApply.getTimeLine().toString()));
            if (!containsSame) {
                throw new ServiceException(ResultCode.SECKILL_TIME_ERROR);
            }
            //检查商品是否参加多个时间段的活动
            if (existSku.contains(seckillApply.getSkuId())) {
                throw new ServiceException(seckillApply.getGoodsName() + "该商品不能同时参加多个时间段的活动");
            } else {
                existSku.add(seckillApply.getSkuId());
            }

        }
    }

    /**
     * 获取秒杀活动信息
     *
     * @return 秒杀活动信息
     */
    private List<SeckillTimelineVO> getSeckillTimelineInfo() {
        List<SeckillTimelineVO> timelineList = new ArrayList<>();
        LambdaQueryWrapper<Seckill> queryWrapper = new LambdaQueryWrapper<>();
        //查询当天时间段内的秒杀活动活动
        Date now = new Date();
        queryWrapper.between(BaseStandardPromotions::getStartTime, DateUtil.beginOfDay(now), DateUtil.endOfDay(now));
//        queryWrapper.ge(BaseStandardPromotions::getEndTime, DateUtil.endOfDay(now));
        List<Seckill> seckillList = this.seckillService.list(queryWrapper);
        for (Seckill seckill : seckillList) {
            //读取系统时间的时刻
            Calendar c = Calendar.getInstance();
            int hour = c.get(Calendar.HOUR_OF_DAY);
            String[] split = seckill.getHours().split(",");
            int[] hoursSored = Arrays.stream(split).mapToInt(Integer::parseInt).toArray();
            Arrays.sort(hoursSored);
            for (int i = 0; i < hoursSored.length; i++) {
                SeckillTimelineVO tempTimeline = new SeckillTimelineVO();
                boolean hoursSoredHour = (hoursSored[i] >= hour || ((i + 1) < hoursSored.length && hoursSored[i + 1] > hour));
                boolean lastHour = i == hoursSored.length - 1 && hoursSored[i] < hour;
                if (hoursSoredHour || lastHour) {
                    SimpleDateFormat format = new SimpleDateFormat(DatePattern.NORM_DATE_PATTERN);
                    String date = format.format(new Date());
                    //当前时间的秒数
                    long currentTime = DateUtil.currentSeconds();
                    //秒杀活动的时刻
                    long timeLine = cn.lili.common.utils.DateUtil.getDateline(date + " " + hoursSored[i], "yyyy-MM-dd HH");

                    Long distanceTime = timeLine - currentTime < 0 ? 0 : timeLine - currentTime;
                    tempTimeline.setDistanceStartTime(distanceTime);
                    tempTimeline.setStartTime(timeLine);
                    tempTimeline.setTimeLine(hoursSored[i]);
                    tempTimeline.setSeckillGoodsList(wrapperSeckillGoods(hoursSored[i], seckill.getId()));
                    timelineList.add(tempTimeline);
                }
            }
        }
        return timelineList;
    }

    /**
     * 组装当时间秒杀活动的商品数据
     * w
     *
     * @param startTimeline 秒杀活动开始时刻
     * @return 当时间秒杀活动的商品数据
     */
    private List<SeckillGoodsVO> wrapperSeckillGoods(Integer startTimeline, String seckillId) {
        List<SeckillGoodsVO> seckillGoodsVoS = new ArrayList<>();
        //List<SeckillApply> seckillApplyList = this.list(new LambdaQueryWrapper<SeckillApply>().eq(SeckillApply::getSeckillId, seckillId));
        List<SeckillApply> seckillApplyList = this.baseMapper.getSeckillList(seckillId);
        if (!seckillApplyList.isEmpty()) {
            List<SeckillApply> collect =
                    seckillApplyList.stream().filter(i -> i.getTimeLine().equals(startTimeline) && i.getPromotionApplyStatus().equals(PromotionsApplyStatusEnum.PASS.name())).collect(Collectors.toList());
            for (SeckillApply seckillApply : collect) {
                GoodsSku goodsSku = goodsClient.getCanPromotionGoodsSkuByIdFromCache(seckillApply.getSkuId());
                if (goodsSku != null) {
                    SeckillGoodsVO goodsVO = new SeckillGoodsVO();
                    BeanUtil.copyProperties(seckillApply, goodsVO);
                    goodsVO.setGoodsImage(goodsSku.getThumbnail());
                    goodsVO.setGoodsId(goodsSku.getGoodsId());
                    if (StringUtils.isNotEmpty(seckillApply.getGoodsId())) {
                        Goods goods = goodsClient.getById(seckillApply.getGoodsId());
                        goodsVO.setGoodsName(goods.getGoodsName());
                    }else {
                        goodsVO.setGoodsName(goodsSku.getGoodsName());
                    }

                    Integer totalQuantity = 0;
                    LambdaQueryWrapper<SeckillApply> queryWrapper = new LambdaQueryWrapper<>();
                    queryWrapper.eq(SeckillApply::getSeckillId, seckillApply.getSeckillId());
                    queryWrapper.eq(SeckillApply::getGoodsId, seckillApply.getGoodsId());
                    List<SeckillApply> seckillApplies = this.list(queryWrapper);
                    if (!seckillApplies.isEmpty()) {
                        int oq = seckillApplies.stream().mapToInt(SeckillApply::getOriginalQuantity).sum();
                        goodsVO.setOriginalQuantity(oq);
                        int virtualSalesNum = seckillApplies.stream().mapToInt(SeckillApply::getVirtualSalesNum).sum();
                        goodsVO.setVirtualSalesNum(virtualSalesNum);

                        /*for (SeckillApply seckillApply1 : seckillApplies) {
                            String promotionGoodsStockCacheKey = PromotionGoodsService.getPromotionGoodsStockCacheKey(PromotionTypeEnum.SECKILL, seckillId,
                                    seckillApply1.getSkuId());
                            Object quantity = cache.get(promotionGoodsStockCacheKey);
                            if (quantity != null) {
                                totalQuantity = totalQuantity + (Integer) quantity;
                            }
                        }*/

                        QueryWrapper<PromotionGoods> queryWrapper1 = new QueryWrapper<>();
                        queryWrapper1.eq("promotion_id", seckillApply.getSeckillId());
                        queryWrapper1.eq("goods_id", seckillApply.getGoodsId());
                        queryWrapper1.select("sum(quantity) as quantity");
                        queryWrapper1.last("limit 1");
                        PromotionGoods promotionGoods = promotionGoodsService.getOne(queryWrapper1);
                        if (null != promotionGoods) {
                            goodsVO.setQuantity(promotionGoods.getQuantity());
                        }else {
                            goodsVO.setQuantity(seckillApplies.stream().mapToInt(SeckillApply::getQuantity).sum());
                        }

                    }


                    seckillGoodsVoS.add(goodsVO);
                }
            }
        }
        return seckillGoodsVoS;
    }

    /**
     * 检测秒杀申请的商品
     *
     * @param seckill      秒杀活动
     * @param seckillApply 秒杀活动申请
     * @param goodsSku     商品SKU
     * @param startTime    秒杀时段开启时间
     */
    private void checkSeckillGoodsSku(Seckill seckill, SeckillApplyVO seckillApply, GoodsSku goodsSku, DateTime startTime) {
        //活动库存不能大于商品库存
        if (goodsSku.getQuantity() < seckillApply.getQuantity()) {
            log.info("校验秒杀库存->skuName:{}, 库存:{},{}", goodsSku.getGoodsName(), goodsSku.getQuantity(), seckillApply.getQuantity());
            throw new ServiceException(seckillApply.getGoodsName() + "，此商品库存不足");
        }
        if (seckillApply.getQuantity() <= 0) {
            throw new ServiceException(seckillApply.getGoodsName() + "，库存必须大于0");
        }
        //查询是否在同一时间段参与了拼团活动
        if (promotionGoodsService.findInnerOverlapPromotionGoods(PromotionTypeEnum.PINTUAN.name(), goodsSku.getId(), startTime,
                seckill.getEndTime(), seckill.getId()) > 0) {
            throw new ServiceException("商品[" + goodsSku.getGoodsName() + "]已经在重叠的时间段参加了拼团活动，不能参加秒杀活动");
        }
        //查询是否在同一时间段参与了秒杀活动活动
        if (promotionGoodsService.findInnerOverlapPromotionGoods(PromotionTypeEnum.SECKILL.name(), goodsSku.getId(), startTime,
                seckill.getEndTime(), seckill.getId()) > 0) {
            throw new ServiceException("商品[" + goodsSku.getGoodsName() + "]已经在重叠的时间段参加了秒杀活动，不能参加秒杀活动活动");
        }
    }

    /**
     * 获取秒杀活动促销商品
     *
     * @param goodsSku     商品SKU
     * @param seckillApply 秒杀活动申请
     * @param seckill      秒杀活动
     * @return 秒杀活动促销商品
     */
    private PromotionGoods setSeckillGoods(GoodsSku goodsSku, SeckillApply seckillApply, Seckill seckill) {
        //设置促销商品默认内容
        PromotionGoods promotionGoods = new PromotionGoods(goodsSku);
        promotionGoods.setPrice(seckillApply.getPrice());
        promotionGoods.setQuantity(seckillApply.getQuantity());
        promotionGoods.setOriginalPrice(seckillApply.getOriginalPrice());
        //设置单独每个促销商品的结束时间
        DateTime startTime = DateUtil.offsetHour(DateUtil.beginOfDay(seckill.getStartTime()), seckillApply.getTimeLine());
        promotionGoods.setStartTime(startTime);
        if (seckill.getEndTime() == null) {
            promotionGoods.setEndTime(DateUtil.endOfDay(startTime));
        } else {
            promotionGoods.setEndTime(seckill.getEndTime());
        }
        return promotionGoods;
    }

    @Override
    public List<SeckillGoodsVO> getSeckillGoodsSkuList (String seckillId, String goodsId) {
        List<SeckillGoodsVO> seckillGoodsVoS = Lists.newArrayList();
        List<SeckillApply> seckillApplyList = this.list(new LambdaQueryWrapper<SeckillApply>().eq(SeckillApply::getSeckillId, seckillId).eq(SeckillApply::getGoodsId, goodsId));
        if (!seckillApplyList.isEmpty()) {
            for (SeckillApply seckillApply : seckillApplyList) {
                GoodsSku goodsSku = goodsClient.getCanPromotionGoodsSkuByIdFromCache(seckillApply.getSkuId());
                if (goodsSku != null) {
                    if (goodsSku.getQuantity() == 0) {
                        continue;
                    }
                    SeckillGoodsVO goodsVO = new SeckillGoodsVO();
                    BeanUtil.copyProperties(seckillApply, goodsVO);
                    goodsVO.setGoodsImage(goodsSku.getThumbnail());
                    goodsVO.setGoodsId(goodsSku.getGoodsId());
                    goodsVO.setGoodsName(goodsSku.getGoodsName());
                    goodsVO.setSkuQuantity(goodsSku.getQuantity());
                    goodsVO.setOriginalPrice(seckillApply.getOriginalPrice());
                    String promotionGoodsStockCacheKey = PromotionGoodsService.getPromotionGoodsStockCacheKey(PromotionTypeEnum.SECKILL, seckillId,
                            seckillApply.getSkuId());
                    Object quantity = cache.get(promotionGoodsStockCacheKey);
                    if (quantity != null) {
                        goodsVO.setQuantity((Integer) quantity);
                    }
                    seckillGoodsVoS.add(goodsVO);
                }
            }
        }else {
            GoodsSearchParams searchParams = new GoodsSearchParams();
            searchParams.setGoodsId(goodsId);
            List<GoodsSku> goodsSkuByList = goodsClient.getGoodsSkuByList(searchParams);
            if (!goodsSkuByList.isEmpty()) {
                for (GoodsSku goodsSku : goodsSkuByList) {
                    if (goodsSku.getQuantity() == 0) {
                        continue;
                    }
                    SeckillGoodsVO goodsVO = new SeckillGoodsVO();
                    goodsVO.setGoodsImage(goodsSku.getThumbnail());
                    goodsVO.setGoodsId(goodsSku.getGoodsId());
                    goodsVO.setGoodsName(goodsSku.getGoodsName());
                    goodsVO.setSkuQuantity(goodsSku.getQuantity());
                    goodsVO.setOriginalPrice(goodsSku.getPrice());
                    goodsVO.setSkuId(goodsSku.getId());
                    goodsVO.setPrice(0D);
                    goodsVO.setQuantity(0);
                    goodsVO.setVirtualSalesNum(0);
                    seckillGoodsVoS.add(goodsVO);
                }
            }
        }
        return seckillGoodsVoS;
    }

}